package view;

import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.border.EtchedBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import modelInterfaces.IMetricSetup;
import pluginInterfaces.IMetric;
import pluginInterfaces.setup.MetricSetup;
import utils.Codes;
import utils.Messages;
import utils.weka.view.GenericObjectEditor;
import utils.weka.view.PropertyDialog;
import viewInterfaces.IViewTestsPanel;
import controller.ControllerMetricsPanel;
import controllerInterfaces.IControllerMetricsPanel;

 /**
 * Presents user interface for add, edit and remove metrics configurations   
 */
public class ViewMetricsPanel extends JPanel implements IViewTestsPanel {

	/** MVC++ Controller
	* @see ControllerMetricsPanel*/	
	private IControllerMetricsPanel myController;
	
	/** Presents list of metrics configurations*/
	private JList listMetric;
	
	/** Button for edit a configuration metric */
	private JButton btnEdit;
	
	/** Button for remove a configuration metric */
	private JButton btnRemove;
	
	/** Button for copy a configuration metric */
	private JButton btnCopy;
	
	/** Button for add a configuration metric */
	private JButton btnAdd;
	
	/**
	 * Class constructor create the panel.
	 */
	public ViewMetricsPanel() {
		
		JPanel panelButtons = new JPanel();
		panelButtons.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
		
		btnAdd = new JButton("Add");
		btnAdd.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				StartToAddMetricSetup();
			}
		});
		panelButtons.add(btnAdd);
		
		btnEdit = new JButton("Edit");
		btnEdit.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if (!listMetric.isSelectionEmpty()){
					StartToEditMetricSetup(listMetric.getSelectedIndex());
				}
				else
				{
					renderError(Codes.errorEditListObject, Messages.errorEditListObject);
				}				
			}
		});
		panelButtons.add(btnEdit);
		
		btnRemove = new JButton("Remove");
		btnRemove.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (!listMetric.isSelectionEmpty()) {
					Object[] options = { "Yes", "No" };
					int n = JOptionPane
							.showOptionDialog(
									null,
									"Are you sure you want to remove metric setup?",
									"Confirm Remove",
									JOptionPane.YES_NO_CANCEL_OPTION,
									JOptionPane.QUESTION_MESSAGE, null,
									options, options[1]);
					if (n == 0) {
						StartToRemoveMetricSetup(listMetric.getSelectedIndex());
					}
				}
				else
				{
					renderError(Codes.errorRemoveListObject, Messages.errorRemoveListObject);
				}				
			}
		});
		panelButtons.add(btnRemove);
		
		btnCopy = new JButton("Copy");
		btnCopy.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (!listMetric.isSelectionEmpty()) {
					Object[] options = { "Yes", "No" };
					int n = JOptionPane
							.showOptionDialog(
									null,
									"Are you sure you want to copy recommender setup?",
									"Confirm Copy",
									JOptionPane.YES_NO_CANCEL_OPTION,
									JOptionPane.QUESTION_MESSAGE, null,
									options, options[1]);
					if (n == 0) {
						StartToCopyMetricSetup(listMetric.getSelectedIndex());
					}
				}
				else
				{
					renderError(Codes.errorCopyListObject, Messages.errorCopyListObject);
				}				
			}
		});
		panelButtons.add(btnCopy);
		
		JPanel panel = new JPanel();
		GroupLayout groupLayout = new GroupLayout(this);
		groupLayout.setHorizontalGroup(
			groupLayout.createParallelGroup(Alignment.LEADING)
				.addGroup(Alignment.TRAILING, groupLayout.createSequentialGroup()
					.addContainerGap()
					.addGroup(groupLayout.createParallelGroup(Alignment.TRAILING)
						.addComponent(panel, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 430, Short.MAX_VALUE)
						.addComponent(panelButtons, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 430, Short.MAX_VALUE))
					.addContainerGap())
		);
		groupLayout.setVerticalGroup(
			groupLayout.createParallelGroup(Alignment.LEADING)
				.addGroup(groupLayout.createSequentialGroup()
					.addContainerGap()
					.addComponent(panelButtons, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
					.addPreferredGap(ComponentPlacement.RELATED)
					.addComponent(panel, GroupLayout.DEFAULT_SIZE, 239, Short.MAX_VALUE)
					.addContainerGap())
		);
		
		listMetric = new JList();
		listMetric.addListSelectionListener(new ListSelectionListener() {
			public void valueChanged(ListSelectionEvent arg0) {
				if(listMetric.isSelectionEmpty())
				{
					btnEdit.setEnabled(false);
					btnRemove.setEnabled(false);
					btnCopy.setEnabled(false);
				}
				else
				{
					btnEdit.setEnabled(true);
					btnRemove.setEnabled(true);
					btnCopy.setEnabled(true);
				}				
			}
		});
		listMetric.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
		GroupLayout gl_panel = new GroupLayout(panel);
		gl_panel.setHorizontalGroup(
			gl_panel.createParallelGroup(Alignment.LEADING)
				.addGroup(gl_panel.createSequentialGroup()
					.addContainerGap()
					.addComponent(listMetric, GroupLayout.DEFAULT_SIZE, 410, Short.MAX_VALUE)
					.addContainerGap())
		);
		gl_panel.setVerticalGroup(
			gl_panel.createParallelGroup(Alignment.LEADING)
				.addGroup(gl_panel.createSequentialGroup()
					.addGap(11)
					.addComponent(listMetric, GroupLayout.DEFAULT_SIZE, 217, Short.MAX_VALUE)
					.addContainerGap())
		);
		panel.setLayout(gl_panel);
		setLayout(groupLayout);

	}

	
	
	/**
	 * Set the MVC++ Controller Class for this View.</br>
	 * ControllerMetricsPanel is manipulable through {@link IControllerMetricsPanel} interface
	 * @param	myController	MVC++ Controller
	 * @see	ControllerMetricsPanel
	 * @see IControllerMetricsPanel
	 */	
	@Override
	public void SetController(IControllerMetricsPanel myController) {
		this.myController = myController;
	}

	
	
	/**
	 * Get panel of metrics configurations
	 * @return	JPanel
	 */
	@Override
	public JPanel GetPanel() {
		return this;
	}



	/**
	 * Show metric setup dialog
	 * @param goe	generic object editor 
	 */
	@Override
	public void renderDialogSetup(GenericObjectEditor goe) {
	      PropertyDialog pd = new PropertyDialog((JFrame) null, goe, 100, 100);
	      pd.setSize(850, 200);
	      pd.setVisible(true);	
	}


	/**
	 * Get all metrics configurations of current JList.</br>
	 * Each of the obtained {@link MetricSetup} are manipulable through its {@link IMetricSetup} interface.
	 * @return metrics configurations list 
	 * @see 	IMetricSetup
	 * @see		MetricSetup
	 */		
	@Override
	public List<IMetricSetup> getMetricSetupList() {
		List<IMetricSetup> metricSetupList = new ArrayList<IMetricSetup>();
		 for(int i = 0; i < listMetric.getModel().getSize(); i++)
		 {
		     metricSetupList.add((IMetricSetup) listMetric.getModel().getElementAt(i));
		 }
		 return metricSetupList;
	}


	/**
	 * Show error dialog
	 * @param code	error code
	 * @param message	error message
	 */
	@Override
	public void renderError(int code, String message) {
		javax.swing.JOptionPane.showMessageDialog(this, code + " - " + message, "Error",javax.swing.JOptionPane.ERROR_MESSAGE);
	}


	/**
	 * Set the list of metric configurations in current JList</br>
	 * Each of the set {@link Metric} is manipulable through its {@link IMetric} interface.
	 * @param	metricList	list of {@link IMetric}
	 * @see 	IMetric
	 * @see		Metric
	 */		
	@Override
	public void setMetricList(List<IMetric> metricList) {
		this.listMetric.setListData(metricList.toArray());
	}


	
	/**
	 * Enables or disables all component of this panel, depending on the value of the parameter value.</br> 
	 * @param value	- If true, this component is enabled; otherwise this component is disabled  
	 */
	public void setEnabledAll(boolean value) {
		Component[] components = this.getComponents();  
		for (int i = 0; i < components.length; i++) 
		{ 
			if( components[i] instanceof JPanel)
			{
				this.setPanelComponentsEnabled(value, (JPanel) components[i]);
			}
		} 
	}
	
	
	
	/**
	 * Enables or disables all components depending on the value of the parameter value and parameter panel</br> 
	 * @param value	- If true, this component is enabled; otherwise this component is disabled  .
	 * @param panel - JPanel that contains components 
	 */	
	private void setPanelComponentsEnabled(boolean value, JPanel panel)
	{
		Component[] components = panel.getComponents(); 
		for (int i = 0; i < components.length; i++) 
		{ 
			components[i].setEnabled(value); 
		} 		
	}	

	
	
	/**
	 * Start process for add a new recommender setup.
	 */
	public void StartToAddMetricSetup() {
		myController.addMetricSetup();
	}	
	

	
	/**
	 * Start process for edit a existing recommender setup.
	 * @param index index of recommender setup to edit
	 */
	public void StartToEditMetricSetup(int index) {
		myController.editMetricSetup(index);
	}
	
	
	
	/**
	 * Start process for remove a existing recommender setup.
	 * @param index index of recommender setup to remove
	 */
	public void StartToRemoveMetricSetup(int index) {
		myController.removeMetricSetup(index);
	}

	
	/**
	 * Start process for copy a existing recommender setup.
	 * @param index index of recommender setup to copy
	 */
	public void StartToCopyMetricSetup(int index) {
		myController.copyMetricSetup(index);
	}
}
